package com.example.teacher.Service.Impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.constants.MqConstants;
import com.example.common.constants.TakeConstants;
import com.example.common.domain.Messages.Mgs;
import com.example.common.domain.dto.SignInDto;
import com.example.common.domain.pojo.*;
import com.example.common.enums.SignInStatus;
import com.example.teacher.Converter.AttendanceConverter;
import com.example.teacher.Service.*;
import com.example.teacher.mapper.AttendanceMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AttendanceServiceImpl extends ServiceImpl<AttendanceMapper, Attendance> implements AttendanceService {
    @Autowired
    private AttendanceMapper attendanceMapper;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private ClassStudentService classStudentService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private CourseService courseService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private MessageConverter jsonMessageConverter;

    @Override
    public void sendSignInNotification(SignInDto sign) {
        try {
            // 1. 从缓存获取教师信息（使用缓存穿透策略）
            Teacher teacher = teacherService.getTeacherByIdWithLogicalExpire(sign.getTeacherId());
            // 2. 从缓存获取课程信息
            Course course = courseService.getCourseByIdWithLogicalExpire(sign.getCourseId());
            sign.setTeacherName(teacher.getName());
            sign.setCourseName(course.getName());
            // 3. 构建通知对象
            Mgs mgs = new Mgs(TakeConstants.SIGN_IN, sign, LocalDateTime.now());
            mgs.setSender(teacher.getId());
//            String json = mapper.writeValueAsString(mgs);
//            log.info("序列化结果：{}", json);
//            Mgs mgs1 = new Mgs(TakeConstants.SIGN_IN, json);
            System.out.println("发送到MQ（异步处理:");
            // 4. 发送到MQ（异步处理）
            rabbitTemplate.setMessageConverter(jsonMessageConverter);
            rabbitTemplate.convertAndSend(MqConstants.EXCHANGE_NOTIFICATION, "", mgs);//保存到数据库
            log.info("签到通知发送成功: {}", sign);
        } catch (Exception e) {
            log.error("签到通知发送失败", e);
            throw new RuntimeException("签到通知发送失败", e);
        }
    }

    @Transactional(rollbackFor = Exception.class) // 声明式事务
    public void saveAttendance(SignInDto dto) {
        //获取班级学生信息
        List<ClassStudent> students = classStudentService.getClassStudentByIdWithLogicalExpire(dto.getClassId());
        if (students == null) {
            log.info("班级学生信息为空，无需保存签到信息");
            return;
        }
        List<Student> studentList = studentService.getStudentByIdWithLogicalExpireIds(students.stream().map(ClassStudent::getStudentId).toList());
        // 构建学生ID到姓名的映射
        Map<String, String> studentIdToNameMap = studentList.stream()
                .collect(Collectors.toMap(Student::getId, Student::getName));
// 准备批量插入的签到记录
        // 1. 定义开始时间（秒级时间戳）和有效时长
        long startTimestampSeconds = dto.getStartTime().getTime() / 1000; // 秒级时间戳
        int validMinutes = dto.getValidMinutes(); // 有效时长 30 分钟
        // 2. 转换为毫秒级时间戳（Timestamp 构造器接受毫秒）
        long startTimestampMillis = startTimestampSeconds * 1000;
        Timestamp startTime = new Timestamp(startTimestampMillis);
        // 3. 计算结束时间：开始时间 + 有效时长（分钟转毫秒）
        long endTimestampMillis = startTime.getTime() + (validMinutes * 60 * 1000L);
        Timestamp endTime = new Timestamp(endTimestampMillis);
        List<Attendance> attendanceList = new ArrayList<>();
        for (ClassStudent classStudent : students) {
            String studentId = classStudent.getStudentId();
            Attendance attendance = AttendanceConverter.convertToAttendance(dto, studentId);
            // 设置学生姓名（从映射中获取）
            String studentName = studentIdToNameMap.getOrDefault(studentId, "未知姓名");
            attendance.setClassId(dto.getClassId());
            attendance.setStatus(SignInStatus.NOT_SIGNED);
            attendance.setStartTime(dto.getStartTime());
            attendance.setEndTime(endTime);
            attendance.setStudentName(studentName); // 确保 Attendance 类有 setStudentName 方法
            attendance.setSignId(dto.getSignId());
            attendance.setCode(dto.getSignCode());
            attendance.setValidMinutes(dto.getValidMinutes());
            attendance.setTeacherName(dto.getTeacherName());
            attendance.setCourseId(dto.getCourseId());
            attendance.setCourseName(dto.getCourseName());
            attendance.setTeacherId(dto.getTeacherId());
            attendanceList.add(attendance);
        }
        // 批量插入（根据你使用的框架选择实现方式）
        super.saveBatch(attendanceList);  // 或者使用 MyBatis Plus 的 saveBatch
    }


}
